package com.tools.starter.swagger.runner;
import com.tools.starter.swagger.sqlite.MockEntity;
import com.tools.starter.swagger.sqlite.SQLiteHelper;
import com.tools.starter.swagger.sqlite.SQLiteManager;
import com.tools.starter.swagger.sqlite.SQLiteProperties;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import springfox.documentation.service.Documentation;
import springfox.documentation.spring.web.DocumentationCache;
import springfox.documentation.spring.web.json.JsonSerializer;
import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author com.tools
 * @version 1.0
 * @Description: SwaggerSqliteCommandLineRunner  ApplicationRunner  @PostConstruct注解
 * <com.tools.starter.swagger.runner>
 * @date Created in 2020/8/28 10:39
 **/
@Slf4j
@Component
public class SwaggerSqliteCommandLineRunner implements ApplicationRunner{

    private Connection sqlite = null;

    public static final String DEFAULT_URL = "/v2/api-docs";
    private static final String HAL_MEDIA_TYPE = "application/hal+json";
    private String hostNameOverride;
    @Autowired
    private Environment environment;
    @Autowired
    private DocumentationCache documentationCache;
    @Autowired
    private ServiceModelToSwagger2Mapper mapper;
    @Autowired
    private JsonSerializer jsonSerializer;

    @Autowired
    private SQLiteHelper sqLiteHelper;

    /*static {
        sqlite = SQLiteHelper.buildDataSource(new SQLiteProperties);
    }*/

    // 初始化SQLite数据库 表
    @Override public void run(ApplicationArguments args)
        throws Exception {
        sqlite = sqLiteHelper.buildDataSource();
        log.info("Application.run start");
        SQLiteManager.setConnection(sqlite);
        this.hostNameOverride = environment.getProperty("springfox.documentation.swagger.v2.host", "DEFAULT");
        if (Objects.isNull(sqlite)) {
            throw new RuntimeException("sqlite connection is null");
        }
        // 判断并创建表 仅判断一个表 后期更新新表
        final Statement stmt = sqlite.createStatement();
        ResultSet resultSet = stmt.executeQuery("select count(*) as total from sqlite_master where type='table' and name = 'MOCK' order by name;");
        log.info("count mock:{}", resultSet.getInt("total"));
        if (resultSet.getInt("total") < 1) {
            String sql = "CREATE TABLE MOCK\n" + "(\n" + "  id        INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,        -- 主键\n"
                + "  tags      CHAR(100),                                         -- 接口标签\n"
                + "  summary   CHAR(100),                                         -- method标签\n"
                + "  path_url  CHAR(256)                         NOT NULL unique , -- 接口地址\n"
                + "  mock_data TEXT                              NOT NULL         -- 接口mock数据\n" + ");";
            stmt.executeUpdate(sql);
        }
        Documentation documentation = this.documentationCache.documentationByGroup("default");
        if (Objects.nonNull(documentation)) {
            Swagger swagger = this.mapper.mapDocumentation(documentation);
            // 初始化表
            Map<String, Path> pathMap = swagger.getPaths();
            if (Objects.nonNull(pathMap) && !pathMap.isEmpty()) {
                // 添加数据到数据库
                pathMap.forEach((key,value) -> {
                    MockEntity entity = new MockEntity();
                    List<Operation> paths = value.getOperations();
                    entity.setTags(paths.get(0).getTags().toString());
                    entity.setSummary(paths.get(0).getSummary());
                    entity.setPathUrl(key);
                    entity.setMockData(null);
                    try {
                        SQLiteManager.save(entity, stmt);
                    } catch (Exception e) {
                        log.error("path to database error");
                    }
                });
            }
        }
        stmt.close();

        log.info("Application.run end");
    }
}
